/**
  ******************************************************************************
  * @file    master_app.c
  * @author  
  * @version V1.1
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; COPYRIGHT 2021 Shanghai Macrogiga Electronics</center></h2>
  *
  ******************************************************************************
  */
#include <string.h>
#include "mg_driver.h"
#include "mg_ble_control_master.h"
#include "mg_ble_control.h"
#include "mg_driver_uart.h"


#define MASTER_SWITCH_MAX_TIME (10) /*sleep counter*/

extern u8 target_ble_addr[6];
extern u8 target_ble_found_flag;
extern unsigned char IsTickTimeout(unsigned int target);
extern unsigned int GetSysTickCount(void);


void uart_show_hex(u8 data)
{
    u8 part;
    
    part = (data >> 4)& 0x0F;
    if(part > 9)
    {
        UART_SendOneByte('A'+(part-10));while(!UART_Get_TX_Flag());
    }
    else
    {
        UART_SendOneByte('0'+(part));while(!UART_Get_TX_Flag());
    }
    
    part = (data)& 0x0F;
    if(part > 9)
    {
        UART_SendOneByte('A'+(part-10));while(!UART_Get_TX_Flag());
    }
    else
    {
        UART_SendOneByte('0'+(part));while(!UART_Get_TX_Flag());
    }
    
    UART_SendOneByte(' ');while(!UART_Get_TX_Flag());
    
}
void uart_show_info_hex(u8* data, u8 len)
{
    while(len)
    {
        uart_show_hex(*data);
        data++;
        len --;
    }
    
    UART_SendOneByte(0x0D);while(!UART_Get_TX_Flag());
    UART_SendOneByte(0x0A);while(!UART_Get_TX_Flag());
}

void uart_show_info(u8* data, u8 len)
{
    while(len)
    {
        UART_SendOneByte(*data);while(!UART_Get_TX_Flag());
        data++;
        len --;
    }
    
    UART_SendOneByte(0x0D);while(!UART_Get_TX_Flag());
    UART_SendOneByte(0x0A);while(!UART_Get_TX_Flag());
}

static u32 master_timeout_tick = 0;

void set_master_role_timeout(void)
{
    master_timeout_tick = GetSysTickCount() + MASTER_SWITCH_MAX_TIME;
}

void check_scan_timeout(void)
{
    if(IsTickTimeout(master_timeout_tick))//time out
    {
        MgBle_CentralScan_Stop();
    }    
}

void ScanProcCallback(u8 evt, u8* contxt) //master scan callback
{
    BLE_DEV_INFO* dev = (BLE_DEV_INFO*) contxt;
    
    switch(evt)
    {
        case TXRX_IDLE:
            //add some control code here
            check_scan_timeout();
        
            break;
        
        case TXRX_RX_NEW_DATA: //find device's adv data
            if(dev->adv[0])
            {
                uart_show_info_hex(dev->addr,6);
//                uart_show_info_hex(dev->adv,31);
            }
            
            if(dev->rsp[0])
            {
                //to do...
//                uart_show_info_hex(dev->rsp,31);
            }
            uart_show_info_hex(&(dev->rssi),1);
            
            //check whether it is the target device, here just an example, one may chage it....
            if(((signed char)dev->rssi) > -65 /*rssi value*/)//4F 26 00 04 69 ED
            {
                if((dev->addr[5] == 0xED) && (dev->addr[4] == 0x69)) //save the addr and stop the scan if any....
                {
                    memcpy(target_ble_addr,dev->addr,6);
                    target_ble_found_flag = 1;
                    
                    MgBle_CentralScan_Stop();
                    
                    uart_show_info("found target device...",22);
                }
            }

            break;
        
        default://error
            break;
    }
}

void MgBle_ConnStatusUpdate_Central(u8 Status /*CENTRAL_CONNECT_XXXXX*/)
{
    switch(Status)
    {
        case CENTRAL_CONNECT_CONNECTED:
            uart_show_info("master connected...",19);
            break;
        
        case CENTRAL_CONNECT_DISCONNECTED:
            target_ble_found_flag = 0; //end of connect
            uart_show_info("master disconnected...",22);
            //auto switch the role to slave....
            break;
        
        case CENTRAL_CONNECT_ATTEMPT_FAILED:
            target_ble_found_flag = 0; //end of attempt
            uart_show_info("master connect attempt end...",29);
            //auto switch the role to slave....
            break;
        
        default:break; //error
    }
}

//BB envoked once at each BB sleep stage
void MasterProcCallback(u8 evt, u8* contxt) //master connection callback
{
    //to do...
}

//data coming from slave device(notify & indication)
void CALLBACK_Master_UsrDataOut(u16 handle, u8* data, u8 len)
{
    
}

//BB envoked once at each connected empty stage, one can send(write/read op) data here
void CALLBACK_Master_gatt_user_write_data(void)
{
//    static u8 count = 0;
//    count ++;
    
//    if(count >= 50)
    {
//        count = 0;
        //mconn_writedata(0x10,"abc",3);
//        mconn_findByTypeValueReq(0xff01);
//        mconn_readByGrpReq(0x01,0xffff,PRIMARY_SERVICE_UUID);
//        mconn_readByTypeReq(0x06+0x55,0x0f+0x55,CHARACTER_UUID);
//        MgBle_Master_Disconnect();
    }
}

//Error Response API
void CALLBACK_Master_AttError(u8 ReqOpCode,u8 *par/*handle16,reason8*/) //porting API
{   
    switch(ReqOpCode)
    {
        case ATT_FIND_BY_TYP_REQ: //find by type value req(may dedicate the primay service searching op's response)
            break;
        
        case ATT_RD_BY_TYPE_REQ:
            break;
        
        case ATT_RD_BY_GROUP_TYPE_REQ:
            break;
        
        case ATT_FIND_INFO_REQ:
            break;
        
        case ATT_RD_REQ:
            break;
        
        default:break;
    }
}

//default un-processed gatt data if any.
void CALLBACK_Master_gatt_default(u8 Opcode,u8* par_data, u8 len)
{
    switch(Opcode)
    {
        case ATT_FIND_BY_TYP_RSP:
            //par_data : handle_st, handle_end
            break;
        
        case ATT_RD_BY_GROUP_TYPE_RSP:
            //par_data : group length {handle_st, handle_end, uuid}
            break;
        
        case ATT_RD_BY_TYPE_RSP:
            //par_data : group length {handle16, property8, handle16, uuid}
            break;
        
        case ATT_READ_RSP:
            //par_data : att_value
            break;
        case ATT_FIND_INFO_RSP:
            //par_data : format8, handle16, uuid 
            //format: 0x01 uuid16
            break;
        
        default:break;
    }
}
